﻿// 13.函数.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//


//函数的声明和定义

/*
返回值的数据类型 函数名(参数一的数据类型 参数一, 参数二的数据类型 参数二, ……)
{
    实现函数功能的代码。
        return 返回值;
}
*/

//例如实现一个简单的加法函数
int Add(int x, int y)      //函数声明
{
    int z = x + y;         //实现函数功能的代码。
    return z;              //return 返回值;
}

//函数的声明：让编译器知道函数的存在，包括返回值的数据类型、函数名和参数列表。
//函数的定义：函数的实现过程。

/*
注意：
 函数的声明和定义可以书写在一起，也可以分开，如果书写在一起，一般放在 main 函数的上面，
   如果分开，一般在 main 函数的上面声明，在 main 函数的下面定义。
 如果函数的声明和定义分开书写，函数的声明后面一定要有分号，函数的定义后面一定不能写分号。
 在同一个程序中，函数只需要声明和定义一次，也可以多次声明，但只能定义一次。
 函数的声明必须和函数的定义一致（返回值的数据类型、函数名和参数列表），如果函数名和参数列表不同，表示它们不是同一个函数。
 return 语句返回值的数据类型必须与函数的声明一致。
 在函数体中，return 语句可以多次使用。
 如果函数的重点是实现功能，不关心返回值，返回值的数据类型填 void，return 语句后面就空着。
 函数可以没有任何参数。
 函数名是标识符，必须满足标识符的命名规则。
 在函数的声明和函数的定义中，参数命名可以不同，但是没必要这么书写。
*/

/*
函数的调用
语法：函数名(参数一, 参数二, ……)
注意：
 声明函数的代码必须放在调用之前，定义函数的代码可以放在调用之后。
 调用函数的时候，参数列表必须与函数的声明一致（参数的个数、书写的顺序和数据类型）。
 不管在什么地方，都不能调用 main 函数，但是，在普通函数中，可以调用其它的普通函数。
 调用函数的代码可以独占一条语句，也可以用于表达式（赋值运算、算术运算、关系运算、函数的参数）。
 如果函数用于表达式中，返回值的数据类型要匹配（否则可能会被隐式转换或编译错误）。
 如果函数有返回值，可以不关心它，忽略它。

*/


//写一个函数，给它两个整数，让它比较两个整数的大小，返回较大的那个整数。
//写一个函数，在控制台输出九九乘法表。
//写一个函数，给它两个参数：no - 超女编号，str - 表白的内容。
/*
#include <iostream>                             //io流输入，包含头文件
using namespace std;                            //指定缺省的命名空间

int Max(int x, int y)                           //比较大小函数
{
    if (x < y)
        return y;
    else
        return x;
}

void Print_mt()                                 //打印9*9乘法表函数
{
    int i = 0;
    cout << "\n9*9乘法表:\n" << endl;
    for (i =1; i < 10; i++)
    {
        int j = 0;
        for (j = 1; j <= i; j++)
        {       
            cout << j << " * " << i << " = " << j * i << "  ";
        }
        cout << endl;
    }
    return;                                   //不需要返回
}

void Print_ss(int no, string str)
{
    cout << "亲爱的" << no << "号超女妹妹" << str << endl;
    return;
}
int main()
{

    int x = 8, y = 6;
    int z = Max(x, y);
    cout << " z = " << z <<endl;
    cout << "Max(5,9) = " << Max(5, 9) << endl;
    Print_mt();                               //打印乘法表
    Print_ss(8,"请给我5块钱买雪糕！");
}
*/
 
//变量的作用域
/*
作用域是指程序中变量存在（或生效）的区域，超过该区域变量就不能被访问。
变量分全局变量和局部变量两种，全局变量在整个程序中都可以访问，局部变量只能在函数或语句块
的内部才能访问。

C++中定义变量的场景主要有五种：
1）在全部函数外面定义的是全局变量。
2）在头文件中定义的是全局变量。
3）在函数和语句块内部定义的是局部变量。
4）函数的参数是该函数的局部变量。
5）函数内部用 static 修饰的是静态局部变量。

1）全局变量
在整个程序生命周期内都是有效的，在定义位置之后的任意函数中都能访问。
全局变量在主程序退出时由系统收回内存空间。

2）局部变量
在函数或语句块内部的语句使用，在函数或语句块外部是不可用的。
局部变量在函数返回或语句块结束时由系统收回内存空间。

3）静态局部变量
用 static 修饰的局部变量生命周期和程序相同，并且只会被初始化一次。
其作用域为局部，当定义它的函数或语句块结束时，其作用域随之结束。
当程序想要使用全局变量的时候应该先考虑使用 static（考虑到数据安全性）。

4）注意事项
 全局变量和静态局部变量自动初始化为 0。
 局部变量不会自动初始化，其值是不确定的，程序中应该有初始化局部变量的代码，否则编译可能会报错（不同的编译器不一样）。
 局部变量和全局变量的名称可以相同，在某函数或语句块内部，如果局部变量名与全局变量名相同，
   就会屏蔽全局变量而使用局部变量，如果想使用全局变量，可以在变量名前加两个冒号（::）。
 for 循环初始化语句中定义的变量的作用域是 for 语句块。
*/

/*
函数参数的传递
调用函数的时候，调用者把数值赋给了函数的参数。
实参：调用者程序中书写的在函数名括号中的参数，可以是常量、变量和表达式。
形参：函数的参数列表。
在函数定义的代码中，修改形参的值，会不会影响实参。
*/

/*
#include<iostream>
using namespace std;

void func(int no, string message)            //形参，只是实参的一份临时拷贝，形参也有自己的地址
{
    no = 5; message = "我是一只小小鸟";      //在函数定义的代码中，修改形参的值，会不会影响实参
    cout << "亲爱的" << no << "号超女妹妹" << message << endl;          //仅打印此信息并不会改变实参的值
    return;
}

void func1(int no, string message)            
{
    cout << "亲爱的" << no << "号超女" << message << endl;          
    return;
}

int main()
{
    int number = 3;                                                   //超女编号
    string message = "小姐姐身材真棒，颜值在线，我好喜欢！";          //超女表白内容
    cout << "亲爱的" << number << "号超女妹妹" << message << endl;

    //第2个超女小姐姐信息
    func(number, message);                  //实参

    //第3个超女小姐姐信息
    int no = 8;
    string str = "梨形身材也很吸引人！";
    cout << "亲爱的" << no << "号超女妹妹" << str << endl;

    //第4位超女妹妹信息
    func1(7, "小姐姐真漂亮！");
}
*/


/*
VS 中调试程序
F9 设置 / 取消断点。
F5 / F10 开始调试。
Shift + F5 放弃调试。
F10 逐过程执行。
F11 逐语句执行（可进入函数内部）。
局部变量窗口显示了变量的值，也可以修改
*/